//chapter11.h
#ifndef _CHAPTER11_h_
#define _CHAPTER11_h_
/*
class Bitmap{};
class Widget{
    public:
        void swap(Widget & rhs);
    private:
        Bitmap* pb;
};
*/

// bad case
// 问题1:自我赋值，如果赋值的是本身，delete pb之后，pb = new Bitmap(*rhs.pb)的结果是，pb指向一个被删除的对象
// 问题2:异常安全性，如果 pb = new Bitmap(*rhs.pb)中，new失败，则*this中的pb指向一个被删除的对象
/*
Widget & Widget::operator=(const Widget & rhs){
    delete pb;
    pb = new Bitmap(*rhs.pb);
    return *this;
}
*/

// 解决 “自我赋值” 的办法
/*
Widget & Widget::operator=(const Widget & rhs){
    if (this == &rhs) return *this; // 证同测试（identity test）,如果是自我赋值，不做任何事
    delete pb;
    pb = new Bitmap(*rhs.pb);
    return *this;
}
*/

// 最佳实践, 解决"异常安全性"的同时，解决"自我赋值"带来的问题
// 利用 “精心设计的语句顺序”
// 如果new Bitmap(*rhs.pb)报异常，是不会执行到 delete 的
// 如果“自我赋值”，new Bitmap(*rhs.pb)会利用复制构造函数，创建新的对象，再赋值给pb
/*
Widget & Widget::operator=(const Widget & rhs){
    Bitmap * pOrig = pb; // 记住原先的pb
    pb = new Bitmap(*rhs.pb); // 令pb指向*pb的一个复件(副本)
    delete pOrig; // 删除原来的pb
    return *this;
}
*/

// 最佳实践, 解决"异常安全性"的同时，解决"自我赋值"带来的问题
// 利用 “copy and swap”
/*
Widget & Widget::operator=(const Widget & rhs){
    Widget temp(rhs); // 将 rhs 制作一份复件
    swap(temp);       // 将*this数据和上述复件的数据交换
    return *this;
}
*/



#endif